/*
 * Copyright 2021 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "powermanager.h"

PowerManager::PowerManager(QObject *parent)
    : QObject(parent)
    , m_settings(new QSettings(POWER_MANAGER_CONF_PATH, QSettings::NativeFormat))
    , m_fileWatcher(new QFileSystemWatcher)
    , m_iface(new QDBusInterface(
          POWER_MANAGEMENT_SERVICE,
          POWER_MANAGEMENT_PATH,
          POWER_MANAGEMENT_INTERFACE_NAME,
          QDBusConnection::systemBus()))
{
    if (m_settings->status() != QSettings::NoError) {
        qCritical() << "qsettings init error!";
    }
    m_fileWatcher->addPath(POWER_MANAGER_CONF_PATH);
    connect(m_fileWatcher, &QFileSystemWatcher::fileChanged, this, [=](QString filePath) {
        qDebug() << "file changed" << m_fileWatcher->files();
        m_fileWatcher->addPath(filePath);
        m_settings->sync();
        QStringList diffData = diffSysData();
        qDebug() << "diff data type is :" << diffData;
        emit configChanged(diffData);
    });
    getConfData();
}

PowerManager::~PowerManager() {}

void PowerManager::getConfData()
{
    m_settings->sync();
    m_settings->beginGroup(CONFIG);
    m_sysData.sysPowerPolicyAc = m_settings->value(POWER_POLICY_AC).toInt();
    m_sysData.sysSleepComputerAc = m_settings->value(SLEEP_COMPUTER_AC).toInt();
    m_sysData.sysSleepDisplayAc = m_settings->value(SLEEP_DISPLAY_AC_KEY).toInt();
    m_sysData.sysPowerPolicyBat = m_settings->value(POWER_POLICY_BATTERY).toInt();
    m_sysData.sysSleepComputerBat = m_settings->value(SLEEP_COMPUTER_BATTERY).toInt();
    m_sysData.sysSleepDisplayBat = m_settings->value(SLEEP_DISPLAY_BAT_KEY).toInt();
    m_sysData.sysButtonLidBat = m_settings->value(BUTTON_LID_BATTERY).toString();
    m_sysData.sysButtonLidAc = m_settings->value(BUTTON_LID_AC).toString();
    m_sysData.sysBrightness = m_settings->value(BRIGHTNESS).toInt();
    m_sysData.sysLowBattery = m_settings->value(LOW_BATTERY).toInt();
    m_sysData.sysCriticalBattery = m_settings->value(CRITICAL_BATTERY).toInt();
    m_sysData.sysActionCriticalBat = m_settings->value(ACTION_CRITICAL_BATTERY).toString();
    m_sysData.sysBatterySaver = m_settings->value(BATTERY_SAVER).toInt();
    m_sysData.sysBatterySaverPercent = m_settings->value(BATTERY_SAVER_PERCENT).toInt();
    m_sysData.sysBatterySaverAuto = m_settings->value(BATTERY_SAVER_AUTO).toBool();
    m_sysData.sysBatterySaverBrightness = m_settings->value(BATTERY_SAVER_BRIGHTNESS).toBool();
    m_settings->endGroup();
    qDebug() << "init sys data";
}

void PowerManager::setConfigValue(const QString key, const QVariant value)
{
    QDBusVariant v1;
    QVariant v2;
    v1.setVariant(value);
    v2.setValue(v1);
    m_iface->call("SetPowerConfig", key, v2);
}

QVariant PowerManager::getPowerValue(const QString &key)
{
    QVariant value;
    m_settings->sync();
    m_settings->beginGroup(CONFIG);
    value = m_settings->value(key);
    m_settings->endGroup();
    return value;
}

QStringList PowerManager::diffSysData()
{
    QStringList str;
    QHash<QString, QVariant> cache;
    int data1;
    QString data2;
    bool data3;
    m_settings->beginGroup(CONFIG);
    str = m_settings->childKeys();
    for (int var = 0; var < str.size(); ++var) {
        cache.insert(str.at(var), m_settings->value(str.at(var)));
    }
    m_settings->endGroup();
    str.clear();
    str << dataJudgment(POWER_POLICY_AC, m_sysData.sysPowerPolicyAc, data1 = cache.value(POWER_POLICY_AC).toInt());
    str << dataJudgment(
        SLEEP_COMPUTER_AC, m_sysData.sysSleepComputerAc, data1 = cache.value(SLEEP_COMPUTER_AC).toInt());
    str << dataJudgment(
        SLEEP_DISPLAY_AC_KEY, m_sysData.sysSleepDisplayAc, data1 = cache.value(SLEEP_DISPLAY_AC_KEY).toInt());

    str << dataJudgment(BUTTON_LID_AC, m_sysData.sysButtonLidAc, data2 = cache.value(BUTTON_LID_AC).toString());
    str << dataJudgment(BRIGHTNESS, m_sysData.sysBrightness, data1 = cache.value(BRIGHTNESS).toInt());
    str << dataJudgment(LOW_BATTERY, m_sysData.sysLowBattery, data1 = cache.value(LOW_BATTERY).toInt());
    str << dataJudgment(BATTERY_SAVER, m_sysData.sysBatterySaver, data1 = cache.value(BATTERY_SAVER).toInt());
    str << dataJudgment(
        POWER_POLICY_BATTERY, m_sysData.sysPowerPolicyBat, data1 = cache.value(POWER_POLICY_BATTERY).toInt());
    str << dataJudgment(
        BUTTON_LID_BATTERY, m_sysData.sysButtonLidBat, data2 = cache.value(BUTTON_LID_BATTERY).toString());
    str << dataJudgment(CRITICAL_BATTERY, m_sysData.sysCriticalBattery, data1 = cache.value(CRITICAL_BATTERY).toInt());
    str << dataJudgment(
        SLEEP_DISPLAY_BAT_KEY, m_sysData.sysSleepDisplayBat, data1 = cache.value(SLEEP_DISPLAY_BAT_KEY).toInt());
    str << dataJudgment(
        SLEEP_COMPUTER_BATTERY, m_sysData.sysSleepComputerBat, data1 = cache.value(SLEEP_COMPUTER_BATTERY).toInt());
    str << dataJudgment(
        BATTERY_SAVER_AUTO, m_sysData.sysBatterySaverAuto, data3 = cache.value(BATTERY_SAVER_AUTO).toBool());
    str << dataJudgment(
        ACTION_CRITICAL_BATTERY,
        m_sysData.sysActionCriticalBat,
        data2 = cache.value(ACTION_CRITICAL_BATTERY).toString());
    str << dataJudgment(
        BATTERY_SAVER_PERCENT, m_sysData.sysBatterySaverPercent, data1 = cache.value(BATTERY_SAVER_PERCENT).toInt());
    str << dataJudgment(
        BATTERY_SAVER_BRIGHTNESS,
        m_sysData.sysBatterySaverBrightness,
        data3 = cache.value(BATTERY_SAVER_BRIGHTNESS).toBool());
    str.removeAll(QString(""));
    return str;
}

bool PowerManager::compareSetValue(const QString &value)
{
    bool ret = false;
    if (0 == value.compare("shutdown") || 0 == value.compare("suspend") || 0 == value.compare("blank")
        || 0 == value.compare("hibernate") || 0 == value.compare("nothing")) {
        ret = true;
    }
    return ret;
}

template <typename data>
QString PowerManager::dataJudgment(const QString &type, data &D1, data &D2)
{
    if (D1 != D2) {
        D1 = D2;
        return type;
    } else {
        return "";
    }
}

QString PowerManager::getActionCriticalBat()
{
    return m_sysData.sysActionCriticalBat;
}

int PowerManager::getBatterySaver()
{
    return m_sysData.sysBatterySaver;
}

bool PowerManager::getBatterySaverAuto()
{
    return m_sysData.sysBatterySaverAuto;
}

bool PowerManager::getBatterySaverBrightness()
{
    return m_sysData.sysBatterySaverBrightness;
}

int PowerManager::getBatterySaverPercent()
{
    return m_sysData.sysBatterySaverPercent;
}

int PowerManager::getBrightness()
{
    return m_sysData.sysBrightness;
}

QString PowerManager::getButtonLidAc()
{
    return m_sysData.sysButtonLidAc;
}

QString PowerManager::getButtonLidBat()
{
    return m_sysData.sysButtonLidBat;
}

int PowerManager::getCriticalBattery()
{
    return m_sysData.sysCriticalBattery;
}

int PowerManager::getLowBattery()
{
    return m_sysData.sysLowBattery;
}

int PowerManager::getPowerPolicyAc()
{
    return m_sysData.sysPowerPolicyAc;
}

int PowerManager::getPowerPolicyBat()
{
    return m_sysData.sysPowerPolicyBat;
}

int PowerManager::getSleepComputerAc()
{
    return m_sysData.sysSleepComputerAc;
}

int PowerManager::getSleepComputerBat()
{
    return m_sysData.sysSleepComputerBat;
}

int PowerManager::getSleepDisplayAc()
{
    return m_sysData.sysSleepDisplayAc;
}

int PowerManager::getSleepDisplayBat()
{
    return m_sysData.sysSleepDisplayBat;
}

void PowerManager::setActionCriticalBat(const QString &value)
{
    if (0 == value.compare("shutdown") || 0 == value.compare("hibernate")) {
        setConfigValue(ACTION_CRITICAL_BATTERY, value);
    } else {
        return;
    }
}

void PowerManager::setBatterySaver(const int &value)
{
    setConfigValue(BATTERY_SAVER, value);
}

void PowerManager::setBatterySaverAuto(const bool &value)
{
    setConfigValue(BATTERY_SAVER_AUTO, value);
}

void PowerManager::setBatterySaverBrightness(const bool &value)
{
    setConfigValue(BATTERY_SAVER_BRIGHTNESS, value);
}

void PowerManager::setBatterySaverPercent(const int &value)
{
    setConfigValue(BATTERY_SAVER_PERCENT, value);
}

void PowerManager::setBrightness(const int &value)
{
    setConfigValue(BRIGHTNESS, value);
}

QString PowerManager::setButtonLidAc(const QString &value)
{
    if (compareSetValue(value)) {
        setConfigValue(BUTTON_LID_AC, value);
        return "Set successfully";
    } else {
        return "Data does not meet specifications";
    }
}

QString PowerManager::setButtonLidBat(const QString &value)
{
    if (compareSetValue(value)) {
        setConfigValue(BUTTON_LID_BATTERY, value);
        return "Set successfully";
    } else {
        return "Data does not meet specifications";
    }
}

void PowerManager::setCriticalBattery(const int &value)
{
    setConfigValue(CRITICAL_BATTERY, value);
}

void PowerManager::setLowBattery(const int &value)
{
    setConfigValue(LOW_BATTERY, value);
}

void PowerManager::setPowerPolicyAc(const int &value)
{
    setConfigValue(POWER_POLICY_AC, value);
}

void PowerManager::setPowerPolicyBat(const int &value)
{
    setConfigValue(POWER_POLICY_BATTERY, value);
}

void PowerManager::setSleepComputerAc(const int &value)
{
    setConfigValue(SLEEP_COMPUTER_AC, value);
}

void PowerManager::setSleepComputerBat(const int &value)
{
    setConfigValue(SLEEP_COMPUTER_BATTERY, value);
}

void PowerManager::setSleepDisplayAc(const int &value)
{
    setConfigValue(SLEEP_DISPLAY_AC_KEY, value);
}

void PowerManager::setSleepDisplayBat(const int &value)
{
    setConfigValue(SLEEP_DISPLAY_BAT_KEY, value);
}
